package org.shan.lf.sever.config;

import com.mlnx.common.entity.Response;
import org.shan.lf.common.enums.ResponseEnum;
import org.shan.lf.entity.UserAccount;
import org.shan.lf.service.UserService;
import org.shan.lf.sever.exception.LoginException;
import org.shan.security.core.authorize.AuthorizeConfigProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;


/**
 * Created by amanda.shan on 2019/7/1.
 */
@Configuration
public class AuthConfig {

    @Autowired
    private UserService userService;

    @Bean
    public MlnxWebResponseExceptionTranslator translator() {
        return new MlnxWebResponseExceptionTranslator();
    }

    // 解析接口请求异常的处理类 下面只处理登入异常的情况
    static class MlnxWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {

        @Override
        public ResponseEntity translate(Exception e) throws Exception {

            if (e instanceof LoginException) {
                HttpHeaders headers = new HttpHeaders();
                ResponseEntity response =
                        new ResponseEntity(new Response(ResponseEnum.LOGIN_FAIL.getCode(), e.getMessage()),
                                headers, HttpStatus.FORBIDDEN);

                return response;

            } else {
                return super.translate(e);
            }
        }

    }

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
//        corsConfiguration.addExposedHeader("head1");
        //corsConfiguration.addExposedHeader("Location");
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }

    @Bean
    public UserDetailsService userDetailsService(){
        return new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

                UserAccount userAccount = userService.findUserAccount(username);

                if (userAccount == null) {

                    throw new UsernameNotFoundException(username+ "用户不存在");
                } else {

                    String[] strings = new String[0];

                    return new User(username, userAccount.getPassword(),
                            AuthorityUtils.createAuthorityList(strings));
                }
            }
        };
    }

    @Bean
    public AuthorizeConfigProvider authorizeConfigProvider() {
        return new AuthorizeConfigProvider() {

            @Override
            public boolean config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
                registry.antMatchers("/user/**").permitAll();

                return true;
            }
        };
    }
}
